package com.prs.crm.dao.flow.impl;

import java.util.Collection;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;

import com.prs.crm.dao.flow.WorkFlowDao;
import com.prs.crm.dao.impl.BaseDaoImpl;
import com.prs.crm.domain.flow.WorkFlow;
import com.prs.crm.domain.flow.WorkFlowNode;
import com.prs.crm.domain.flow.WorkFlowTransition;

public class WorkFlowDaoImpl  extends BaseDaoImpl<WorkFlow> implements WorkFlowDao {

	
	public void removeNode(WorkFlowNode node)
	{
		this.getHibernateTemplate().delete(node);
	}
	
	public void removeTransition(WorkFlowTransition trans)
	{
		this.getHibernateTemplate().delete(trans);
	}
	
	@SuppressWarnings("unchecked")
	public Collection<WorkFlow> findByState(final Integer state)
	{
		return (Collection<WorkFlow> )getHibernateTemplate().execute(   
			      new HibernateCallback() {   
			        public Object doInHibernate(Session session) throws HibernateException {   
			        	Criteria criteria =  session.createCriteria(WorkFlow.class);
			        	criteria.add(Restrictions.eq("state", state));
			        	return criteria.list();
			        }   
			      }   
			    );  
	}
	
	public WorkFlowNode exists(final WorkFlow flow,final WorkFlowNode node)
	{
		if (flow==null || flow.getId()==null)
		{
			return null;
		}
		else
		{
			return (WorkFlowNode)getHibernateTemplate().execute(   
			      new HibernateCallback<Object>() {   
			        public Object doInHibernate(Session session) throws HibernateException {   
			            Criteria crit =   
			              session.createCriteria(WorkFlowNode.class);
		
			            crit.add(Restrictions.eq("id", node.getId()));
			            crit.add(Restrictions.eq("flow",flow));
			            List<?> result = crit.list();
			            if (result.size()>0)
			            {
			            	return (WorkFlowNode)result.get(0); 
			            }
			            else
			            {
			            	return null;
			            }
			        }   
			      }   
			    );  
		}
	}
	
	@SuppressWarnings("unchecked")
	public WorkFlowTransition exists(final WorkFlow flow,final WorkFlowTransition transition)
	{
		if (flow==null || flow.getId()==null)
		{
			return null;
		}
		else
		{
			return (WorkFlowTransition)getHibernateTemplate().execute(   
				      new HibernateCallback() {   
				        public Object doInHibernate(Session session) throws HibernateException {   
				            Criteria crit =   
				              session.createCriteria(WorkFlowTransition.class);
				            crit.add(Restrictions.eq("startnode", transition.getStartnode()));
				            crit.add(Restrictions.eq("endnode", transition.getEndnode()));
				            crit.add(Restrictions.eq("flow",flow));
				            List<?> result = crit.list();
				            if (result.size()>0)
				            {
				            	return (WorkFlowTransition)result.get(0); 
				            }
				            else
				            {
				            	return null;
				            }
				        }   
				      }   
				    );  
		}
	}
	
	public void saveFlowNode(WorkFlowNode node)
	{
		if (node.getId()==null)
		{
			this.getHibernateTemplate().save(node);
	
			if (node.getExtra()!=null)
				node.getExtra().setNode(node);
			this.getHibernateTemplate().save(node.getExtra());
		}
		else
		{
			this.getHibernateTemplate().update(node);
			if (node.getExtra()!=null)
				node.getExtra().setNode(node);
			this.getHibernateTemplate().update(node.getExtra());
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<WorkFlow> getWorkFlow(String type) {
		Criteria criteria=this.getSession().createCriteria(WorkFlow.class);
		criteria.createAlias("workFlowType", "wf");
		criteria.add(Restrictions.eq("wf.name", type));
		criteria.add(Restrictions.eq("state", 1));
		return criteria.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<WorkFlow> getAllWorkFlow() {
		Criteria criteria=this.getSession().createCriteria(WorkFlow.class);
		return criteria.list();
	}
}

